#ifndef TRANSFERDAEMON_H
#define TRANSFERDAEMON_H

#include <pthread.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <unistd.h>

#include "protocol.h"
#include "searchablequeue.h"

typedef void requestHandler(normal_request_t request, struct sockaddr_in addr, socklen_t addr_len);
class TransferDaemon
{
public:
    TransferDaemon();
    ~TransferDaemon();
    void startAnswer();
    void sendSync(void* data, int size, struct sockaddr_in addr, socklen_t addr_len);
    void sendInfo(void* data, int size, struct sockaddr_in addr, socklen_t addr_len);
    void sendData(void* data, int size, struct sockaddr_in addr, socklen_t addr_len);
    void setRequestHandler(void* server){
        this->m_visual_server = server;
    }

    friend void* ansSyncThread(void* _tran);
    friend void* ansInfoThread(void* _tran);
    friend void* ansDataThread(void* _tran);
    void setDataSwitch(bool s){
        this->m_data_switch = s;
    }
    bool getDataSwitch(){
        return this->m_data_switch;
    }
    void setInfoSwitch(bool s){
        this->m_info_switch = s;
    }
    bool getInfoSwitch(){
        return this->m_info_switch;
    }

private:
    void answerInfo();
    void answerData();
    void answerSync();
    int establishSocket(int &port);
    requestHandler* m_info_request_handler;
    requestHandler* m_sync_request_handler;
    requestHandler* m_data_request_handler;

    int m_info_port;
    int m_info_sock;
    int m_sync_port;
    int m_sync_sock;
    int m_data_port;
    int m_data_sock;
    sem_t m_info_mutex;
    sem_t m_sync_mutex;
    sem_t m_data_mutex;
    bool m_data_switch;
    bool m_info_switch;
    bool m_working;
    pthread_t m_ans_sync_thread;
    pthread_t m_ans_info_thread;
    pthread_t m_ans_data_thread;

    void* m_visual_server;
};

#endif // TRANSFERDAEMON_H
